/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GrupoD_Final;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.FromContainsFilter;
import org.jivesoftware.smack.filter.NotFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.muc.MultiUserChat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;

public class ImpInstantMessage implements InstantMessage {

    private static final Log LOGGER = LogFactory.getLog(ImpInstantMessage.class);
    public static final String GENERIC_MESSAGE = "GENERIC_MESSAGE";
    private PacketListener listenner;
    XMPPConnection connect = null;
    PacketFilter filter = null;
    MultiUserChat chat = null;
    private String username, password, resource;
    Message msg;
    ArrayList contacts;
    boolean isLogin;

    public ImpInstantMessage() {
    }
//Function login connects the user to the server of googletalk. At the same time add a packet listenner to the connection to recieve,
//in the future, the packets of the other users. In this function it has been saved also the list of contacts. 

    public boolean login(String username, String password, String resource) {

        this.username = username;
        this.password = password;
        this.resource = resource;
        ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
        config.setSASLAuthenticationEnabled(true);
        config.setReconnectionAllowed(true);
        connect = new XMPPConnection(config);
        try {
            connect.connect();
            connect.login(username, password, resource);
            LOGGER.info("User " + username + " is connected");
            this.connect = connect;
            isLogin = true;
            filter = new AndFilter(new PacketTypeFilter(Message.class), new NotFilter(new FromContainsFilter(connect.getUser())));
            connect.createPacketCollector(filter);
            chat = new MultiUserChat(connect, username);
            listenner = (PacketListener) new ImpListener(this);
            connect.addPacketListener(listenner, filter);

            Contacts();



        } catch (Throwable ex) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("User " + username + " can't connect to googleTalk");
            } else {
                LOGGER.info("User " + username + " can't connect to googleTalk");
            }
            LOGGER.fatal("SYSTEM ABORT!");
        }

        return isLogin;

    }
//The function logout disconnect the user of the chat.

    public void logout() {
        if (connect != null) {
            connect.disconnect();
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("User " + username + " is disconnected");
            } else {
                LOGGER.info("User " + username + " is disconnected");
            }
        }
    }
//The function sendMessage recieve a GenericMessage packet and a String with its destination and send the packet to this user. 

    public void sendMessage(String to, ImpGenericMessage igm) {
        msg = new Message();

        msg.setTo(to);
        msg.setPacketID(GENERIC_MESSAGE);
        msg.setProperty(GENERIC_MESSAGE, igm);

        try {

            chat.sendMessage(msg);
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Message send to: " + msg.getTo());
            }
        } catch (XMPPException ex) {
            Logger.getLogger(ImpInstantMessage.class.getName()).log(Level.SEVERE, null, ex);
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Impossible send the message to:" + msg.getTo());
            } else {
                LOGGER.info("Impossible send the message to:" + msg.getTo());
            }
        }

    }
//This function explore the users connected and returns a list with this information

    public ArrayList Contacts() {
        contacts = new ArrayList();
        Roster roster = connect.getRoster();
        for (Iterator<RosterEntry> i = roster.getEntries().iterator(); i.hasNext();) {
            RosterEntry re = (RosterEntry) i.next();
            contacts.add(re.getUser());
        }

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Contacts added to " + username + " list of contacts");
        }
        return contacts;
    }
    //This function print the connected users but isn't neccesary for the correct run of the program. It's an extra function.
    /**
     * public void ImprimeContactos (ArrayList contacts){ Iterator it=
     * contacts.iterator(); System.out.println("Your contats are: "); while
     * (it.hasNext()){ System.out.println(it.next()+ "\n");
     *
     * }
     * }*
     */
}
